<?php
/**
 *
 * @author Strawberry🍓
 * @date 2021-06-21 3:43 下午
 *
 */

namespace app\api\controller;


use app\api\service\HaiDing;
use app\api\service\message;
use app\common\controller\BaseController;
use app\common\energyApi\Energy;
use app\common\model\tang\BalanceLog;
use app\common\model\tang\Cost;
use app\common\model\tang\CostLog;
use app\common\model\tang\CostRule;
use app\common\model\tang\ApiInfo;
use app\common\model\tang\CostSectionPay;
use app\common\model\tang\CostType;
use app\common\model\tang\Merchant as MerchantModel;
use app\common\model\tang\PayInfo;
use app\common\model\tang\SubjectList;
use app\common\model\tang\WatchLog;
use app\common\model\tang\WatchMaintain;
use think\facade\Db;
use think\facade\Log;
use think\facade\Request;

class Notify extends BaseController
{
    public function top_up()
    {
        $this->app->log->info('！！！！！！！余额充值！！！！！！！');
        $param = Request::param();
        $this->app->log->info( var_export($param['resource'], TRUE));
        $infos = $this->decryptToString($param['resource']['associated_data'], $param['resource']['nonce'], $param['resource']['ciphertext']);
        $apiinfo = [
            'api_info' => $infos,
            'type' => 1,
            'time' => date('Y-m-d H:i:s', time())
        ];
        (new ApiInfo())->save($apiinfo);
        $wechat_info = json_decode($infos, true);
        if ($wechat_info['trade_state'] == 'SUCCESS') {
            $this->app->log->info('回调信息');
            $out_trade_no = $wechat_info['out_trade_no'];  // 订单号码
            $total_fee = $wechat_info['amount']['total'];  // 支付金额
            $transaction_id = $wechat_info['transaction_id'];  // 微信返回订单号
            $this->app->log->info('回调信息');
            $info = BalanceLog::with(['merchant'])->where(['order_sn' => $out_trade_no, 'status' => 0])->find();
            Log::record('-----------service_charge------------------');
            if (empty($info)) {
                $this->app->log->info('订单不存在或已经更新');
                exit('订单不存在或已经更新');
            }
            if ($info['amount'] != $total_fee) {
                $this->app->log->info('支付金额不一致');
                exit('支付金额不一致');
            }
            Db::startTrans();
            try {
                $merchant_balance = MerchantModel::where('id', $info->merchant_id)
                    ->value('balance');
                // 记录日志扣减log
                $info->status = 1;
                $info->transaction_id = $transaction_id;
                $info->charge_time = time();
                $info->save();
                // 更新余额
                MerchantModel::where('id', $info->merchant_id)
                    ->inc('balance', $info->amount)
                    ->update();
                $sendMerchant = [];
                $sendMerchant['code'] = $info['code'];
                $sendMerchant['openid'] = $info['openid'];
                $sendMerchant['company'] = $info['company'];
                $sendMerchant['amount'] = $total_fee/100;
                (new message())->charge_success($sendMerchant);
                upMerchantAuto($info->merchant_id);
                $Energy = new Energy();
                //计算用户余额是否足够
                if(bcadd($total_fee,$merchant_balance)>0&&$merchant_balance<0){
                    $watch_list = (new WatchMaintain())->where('merchant_id',$info->merchant_id)->where('type',1)->select();
                    if(!empty($wechat_info)){
                        $watch_list = $watch_list->toArray();
                        Log::info('商户电表列表:'.json_encode($watch_list));
                        $watch= new WatchLog();
                        foreach ($watch_list as $k=>$v){
                            $data = [];
                            $data = [
                                "pointId" => $v['pointId'],
                                "operType" => 2 //1 拉闸2 合闸
                            ];
                            Log::info('合闸请求数据:'.json_encode($data));
                            // 查询月电费接口
                            $port_data = $Energy->universalfunction('remote_disconnect', $data);
                            if(isset($port_data)){
                                $watch->pointId = $data['pointId'];
                                $watch->operType = $data['operType'];
                                $watch->return_info = json_encode($port_data);
                                $watch->create_time = time();
                                $watch->save();
                            }
                        }
                    }
                }
                Db::commit();
                $this->app->log->info('SUCCESS');
                return 'SUCCESS';
            } catch (\Exception $exception) {
                Db::rollback();
                $this->app->log->info('更新失败');
                exit('更新失败');
            }
        }
        $this->app->log->info('没有进来');
    }

    /**
     * 单笔支付
     */
    public function cost()
    {
        $this->app->log->info('！！！！！！！！！1订单缴费！！！！！！！！！');
        $param = Request::param();
        $this->app->log->info(var_export($param['resource'], TRUE));
        $infos = $this->decryptToString($param['resource']['associated_data'], $param['resource']['nonce'], $param['resource']['ciphertext']);
        $apiinfo = [
            'api_info' => $infos,
            'type' => 3,
            'time' => date('Y-m-d H:i:s', time())
        ];
        (new ApiInfo())->save($apiinfo);
        $section = new CostSectionPay(); //分期部分缴费
        $wechat_info = json_decode($infos, true);
        if ($wechat_info['trade_state'] == 'SUCCESS') {
            $out_trade_no = $wechat_info['out_trade_no'];  // 订单号码
            $total_fee = $wechat_info['amount']['total'];  // 支付金额
            $transaction_id = $wechat_info['transaction_id'];  // 微信返回订单号
            $openid = $wechat_info['payer']['sub_openid'];  // 微信用户openid
            $info = Cost::with(['merchant', 'costType'])->where(['order_sn' => $out_trade_no, 'pay_status' => 0])->find();
            if (empty($info)) {
                Log::record('订单不存在或已经更新');
                exit('订单不存在或已经更新');
            }

            $payLog = new PayInfo();
            $payLog->amount = $total_fee;
            $payLog->cost_id = $info['id'];
            $payLog->create_time = time();
            $payLog->type = 1;
            $payLog->save();
            $HDService = new HaiDing();
            $section->all_amount = $info['amount'];
            if ($info['amount'] == $total_fee) {
                $ticket = (new \app\common\model\tang\RepairRecord())->where(['cost_id'=>$info['id']])->find();
                if(!empty($ticket)){
                    (new \app\common\model\tang\RepairRecord())->where(['cost_id'=>$info['id']])->update(['status'=>3]);
                }
                $info->pay_status = 1;
                $info->amount = 0;
                $section->balance_amount = 0;
                $info->pay_amount =$info['all_amount'];
            }else{
                $section->balance_amount = bcsub($info['amount'],$total_fee);
                $info->amount = bcsub($info['amount'],$total_fee);
                $info->pay_amount = bcadd($total_fee,$info['pay_amount']);
                $info->order_sn = OrderSn();
            }
            if(!empty($info['billid'])){
                $payInfo['direction'] = 1;
                $payInfo['paymentMethod'] = 'APP';
                $payInfo['paymentOrderId'] = $info['order_sn'];
                $payInfo['dealer'] = [
                    'uuid'=>'8a0293a988c2d2120188c32b25870098',
                    'code'=>'mianbei',
                    'name'=>'米安贝',
                ];
                $payInfo['paymentDate'] = date('Y-m-d H:i:s',time());
                $payInfo['incomeDate'] = date('Y-m-d H:i:s',time());
                $payInfo['remark'] = '微信小程序收款';
                $payInfo['sourceType'] = 'cre_other';
                $payInfo['lines'] = [
                    [
                        'accId'=>$info['billid'],
                        'total'=>$total_fee/100,
                        'paymentType'=>[
                            'uuid'=>'8a0289aa736f21880173bc84e7a36fa5',
                            'code'=>'009',
                            'name'=>'微信',
                        ],
                        'bankCode'=>'',
                        'poundage'=>''
                    ]
                ];
                $result = $HDService->payInfo($payInfo);
                $costLogInfo = new CostLog();
                $costLog['cost_id'] = $info['id'];
                $costLog['request_info'] = json_encode($payInfo);
                $costLog['responce_info'] = json_encode($result);
                $costLog['happen_time'] =date('Y-m-d H:i:s', time());
                $costLog['create_time'] =  time();
                $costLog['update_time'] =  time();
                $costLogInfo->save($costLog);
                if(isset($result['billNumber'])){
                    $info->return_billid = $result['billNumber'];
                }
            }
            if(in_array($info['cost_type_id'],[51,52,53,54,55,56,57])){
                $costTypeInfo=[];
                $costTypeInfo = (new CostType())->where('id',$info['cost_type_id'])->find();
                $receipt['unitCode'] = $info['merchant']['store_code'];
                $receipt['counterpartCode'] = $info['merchant']['tenant_code'];
                $receipt['dealer'] = [
                    'uuid' => '8a0293a988c2d2120188c32b25870098',
                    'code' => 'mianbei',
                    'name' => '米安贝',
                ];
                $receipt['paymentOrderId'] = $info['order_sn']; //订单编号
                $receipt['contractCode'] = $info['merchant']['code'];//合同号
                $receipt['paymentTypeCode'] = '009'; //付款方式代码
                $receipt['depositDate'] =date( 'Y-m-d H:i:s',time()); //预存日期（收款日期）
                $receipt['accountDate'] =date( 'Y-m-d H:i:s',time());//记账日期
                $receipt['bankCode'] = '';//银行代码
                $receipt['counterContact'] = '';//对方联系人
                $receipt['bankFlowRemark'] = '';
                $receipt['lines'] = [
                    [
                        'subjectCode' => $costTypeInfo['cost_type_id'],
                        'amount' => $total_fee/100,
                        'remark' => '米安贝缴费'
                    ]
                ];
                $result = $HDService->deposit($receipt);
                $costLogInfo = new CostLog();
                $costLog['cost_id'] = $info['id'];
                $costLog['request_info'] = json_encode($receipt);
                $costLog['responce_info'] = json_encode($result);
                $costLog['happen_time'] = date('Y-m-d H:i:s', time());
                $costLog['create_time'] = time();
                $costLog['update_time'] = time();
                $costLogInfo->save($costLog);
                if(isset($result['billNumber'])){
                    $info->return_billid = $result['billNumber'];
                }
            }
            $info->bill_no =  getBill();
//            $info->pay_status = 1;
            $info->openid = $openid;
            $info->pay_time = date('Y-m-d H:i:s', time());
            $info->transaction_id = $transaction_id;
            $info->subject_id = 1;
            $info->save();
            $sendMerchant = [];
            if(!empty($info['merchant'])&&!empty($info['costType'])){
                $sendMerchant['merchant_name'] = $info['merchant']['company'];
                $sendMerchant['code'] = $info['merchant']['code'];
                $sendMerchant['amount'] = $total_fee/100;
                $sendMerchant['cost_name'] =$info['costType']['cost_name'];
                $sendMerchant['openid'] =$openid;
                (new message())->pay_success($sendMerchant);
            }
            $section->merchant_id = $info['merchant_id'];
            $section->transaction_id = $transaction_id;
            $section->cost_id = $info['id'];
            $section->amount = $total_fee;
            $section->create_time = time();
            $section->update_time = time();
            $section->save();
            Log::record('SUCCESS');
            return 'SUCCESS';
        }
        Log::record('没有进来');
//        exit('更新失败');
    }
    /**
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException 合并支付多个订单回调处理
     */
    public function mergeNotify(){
        $this->app->log->info('！！！！！！！！！1订单缴费！！！！！！！！！');
        $param = Request::param();
        $this->app->log->info(var_export($param['resource'], TRUE));
        $infos = $this->decryptToString($param['resource']['associated_data'], $param['resource']['nonce'], $param['resource']['ciphertext']);
        $apiinfo = [
            'api_info' => $infos,
            'type' => 3,
            'time' => date('Y-m-d H:i:s', time())
        ];
        (new ApiInfo())->save($apiinfo);
        $wechat_info = json_decode($infos, true);
        if ($wechat_info['trade_state'] == 'SUCCESS') {
            $out_trade_no = $wechat_info['out_trade_no'];  // 订单号码
            $transaction_id = $wechat_info['transaction_id'];  // 微信返回订单号
            $openid = $wechat_info['payer']['sub_openid'];  // 微信用户openid
            $total_fee = $wechat_info['amount']['total'];  // 支付金额
            $info = Cost::where(['merge_sn'=>$out_trade_no,'pay_status'=>0])->with(['merchant', 'costType'])->select();
            if (empty($info)){
                Log::record('订单不存在或已经更新');
                exit('订单不存在或已经更新');
            }
            $ids = [];
            foreach ($info as $k=>$v){
                $ids[]=$v['id'];
                $ticket = (new \app\common\model\tang\RepairRecord())->where(['cost_id'=>$v['id']])->find();
                if(!empty($ticket)){
                    (new \app\common\model\tang\RepairRecord())->where(['cost_id'=>$v['id']])->update(['status'=>3]);
                }
                if(!empty($v['billid'])){
                    $payInfo['direction'] = 1;
                    $payInfo['paymentMethod'] = 'APP';
                    $payInfo['paymentOrderId'] = $v['order_sn'];
                    $payInfo['dealer'] = [
                        'uuid'=>'8a0293a988c2d2120188c32b25870098',
                        'code'=>'mianbei',
                        'name'=>'米安贝',
                    ];
                    $payInfo['paymentDate'] = date('Y-m-d H:i:s',time());
                    $payInfo['incomeDate'] = date('Y-m-d H:i:s',time());
                    $payInfo['remark'] = '微信小程序收款';
                    $payInfo['sourceType'] = 'cre_other';
                    $payInfo['lines'] = [
                        [
                            'accId'=>$v['billid'],
                            'total'=>$v['amount']/100,
                            'paymentType'=>[
                                'uuid'=>'8a0289aa736f21880173bc84e7a36fa5',
                                'code'=>'009',
                                'name'=>'微信',
                            ],
                            'bankCode'=>'',
                            'poundage'=>''
                        ]
                    ];
                    $HDService = new HaiDing();
                    $result = $HDService->payInfo($payInfo);
                    $costLogInfo = new CostLog();
                    $costLog['cost_id'] = $v['id'];
                    $costLog['request_info'] = json_encode($payInfo);
                    $costLog['responce_info'] = json_encode($result);
                    $costLog['happen_time'] =date('Y-m-d H:i:s', time());
                    $costLog['create_time'] =  time();
                    $costLog['update_time'] =  time();
                    $costLogInfo->save($costLog);
                    if(isset($result['billNumber'])){
                        $costModel['return_billid'] = $result['billNumber'];
                    }
                }
                if(in_array($v['cost_type_id'],[51,52,53,54,55,56,57])){
                    $costTypeInfo=[];
                    $costTypeInfo = (new CostType())->where('id',$v['cost_type_id'])->find();
                    $receipt['unitCode'] = $v['merchant']['store_code'];
                    $receipt['counterpartCode'] = $v['merchant']['tenant_code'];
                    $receipt['dealer'] = [
                        'uuid' => '8a0293a988c2d2120188c32b25870098',
                        'code' => 'mianbei',
                        'name' => '米安贝',
                    ];
                    $receipt['paymentOrderId'] = $v['order_sn']; //订单编号
                    $receipt['contractCode'] = $v['merchant']['code'];//合同号
                    $receipt['paymentTypeCode'] = '009'; //付款方式代码
                    $receipt['depositDate'] =date( 'Y-m-d H:i:s',time()); //预存日期（收款日期）
                    $receipt['accountDate'] =date( 'Y-m-d H:i:s',time());//记账日期
                    $receipt['bankCode'] = '';//银行代码
                    $receipt['counterContact'] = '';//对方联系人
                    $receipt['bankFlowRemark'] = '';
                    $receipt['lines'] = [
                        [
                            'subjectCode' => $costTypeInfo['cost_type_id'],
                            'amount' => $v['amount']/100,
                            'remark' => '米安贝缴费'
                        ]
                    ];
                    $HDService = new HaiDing();
                    $result = $HDService->deposit($receipt);
                    $costLogInfo = new CostLog();
                    $costLog['cost_id'] = $v['id'];
                    $costLog['request_info'] = json_encode($receipt);
                    $costLog['responce_info'] = json_encode($result);
                    $costLog['happen_time'] = date('Y-m-d H:i:s', time());
                    $costLog['create_time'] = time();
                    $costLog['update_time'] = time();
                    $costLogInfo->save($costLog);
                    if(isset($result['billNumber'])){
                        $costModel['return_billid'] = $result['billNumber'];
                    }
                }
                $sendMerchant = [];
                if(!empty($v['merchant'])&&!empty($v['costType'])){
                    $sendMerchant['merchant_name'] = $v['merchant']['company'];
                    $sendMerchant['code'] = $v['merchant']['code'];
                    $sendMerchant['amount'] = $v['amount']/100;
                    $sendMerchant['cost_name'] =$v['costType']['cost_name'];
                    $sendMerchant['openid'] =$openid;
                    (new message())->pay_success($sendMerchant);
                }
                $costModel['pay_status'] = 1;
                $costModel['openid'] = $openid;
                $costModel['pay_amount'] = $v['all_amount'];
                $costModel['amount'] =0;
                $costModel['subject_id'] =1;
                $costModel['bill_no'] =  getBill();
                $costModel['transaction_id'] = $transaction_id;
                $costModel['pay_time'] = date('Y-m-d H:i:s', time());
                (new Cost())->update($costModel, ['id' => $v['id']]);


                $section = new CostSectionPay(); //部分缴费
                $section->merchant_id = $v['merchant_id'];
                $section->transaction_id = '';
                $section->all_amount = $v['all_amount'];
                $section->cost_id = $v['id'];
                $section->amount = $v['amount'];
                $section->balance_amount = 0;
                $section->create_time = time();
                $section->update_time = time();
                $section->type = 1;
                $section->save();

            }
            if(!empty($ids)){
                $payLog = new PayInfo();
                $payLog->amount = $total_fee;
                if (is_array($ids)){
                    $payLog->cost_id = implode(',',$ids);
                }else{
                    $payLog->cost_id = $ids;
                }
                $payLog->create_time = time();
                $payLog->type = 1;
                $payLog->save();
            }
            // 更新余额
            Log::record('SUCCESS');
            return 'SUCCESS';

        }
        Log::record('没有进来');
//        exit('更新失败');
    }


    //罚单直接支付回调
    public function ticketNotify(){
        $this->app->log->info('！！！！！！！罚单支付！！！！！！！');
        $param = Request::param();
        $this->app->log->info( var_export($param['resource'], TRUE));
        $infos = $this->decryptToString($param['resource']['associated_data'], $param['resource']['nonce'], $param['resource']['ciphertext']);
        $apiinfo = [
            'api_info' => $infos,
            'type' => 4,
            'time' => date('Y-m-d H:i:s', time())
        ];
        $section = new CostSectionPay(); //分期部分缴费
        (new ApiInfo())->save($apiinfo);
        Log::info('罚单支付信息:'.$infos);
        $wechat_info = json_decode($infos, true);
        if ($wechat_info['trade_state'] == 'SUCCESS') {
            $this->app->log->info('回调信息');
            $out_trade_no = $wechat_info['out_trade_no'];  // 订单号码
            $openid = $wechat_info['payer']['sub_openid'];  // 微信用户openid
            $transaction_id = $wechat_info['transaction_id'];  // 微信返回订单号
            $total_fee = $wechat_info['amount']['total'];  // 支付金额
            $this->app->log->info('回调信息');
            $info = Cost::with(['merchant', 'costType'])->where(['order_sn'=>$out_trade_no,'pay_status'=>0])->find();
            Log::record('-----------service_charge------------------');
            if (empty($info)) {
                $this->app->log->info('订单不存在或已经更新');
                exit('订单不存在或已经更新');
            }
            $section->all_amount = $info['amount'];
            if ($info['amount'] == $total_fee) {
                $ticket = (new \app\common\model\tang\RepairRecord())->where(['cost_id'=>$info['id']])->find();
                if(!empty($ticket)){
                    (new \app\common\model\tang\RepairRecord())->where(['cost_id'=>$info['id']])->update(['status'=>3]);
                }
                $info->pay_status = 1;
                $info->amount = 0;
                $section->balance_amount = 0;
                $info->pay_amount =$info['all_amount'];
            }else{
                $section->balance_amount = bcsub($info['amount'],$total_fee);
                $info->amount = bcsub($info['amount'],$total_fee);
                $info->pay_amount = bcadd($total_fee,$info['pay_amount']);
                $info->order_sn = OrderSn();
            }

            $payLog = new PayInfo();
            $payLog->amount = $total_fee;
            $payLog->cost_id = $info['id'];
            $payLog->create_time = time();
            $payLog->type = 1;
            $payLog->save();
            $section->merchant_id = $info['merchant_id'];
            $section->transaction_id = $transaction_id;
            $section->cost_id = $info['id'];
            $section->amount = $total_fee;
            $section->create_time = time();
            $section->update_time = time();
            $section->save();
            Db::startTrans();
            try {
                // 记录日志扣减log
                $info->transaction_id = $transaction_id;
                $info->subject_id = 1;
                $info->openid = $openid;
                $info->pay_time = date('Y-m-d H:i:s', time());
                $info->bill_no =  getBill();
                $info->save();
                Db::commit();
                $this->app->log->info('SUCCESS');
                return 'SUCCESS';
            } catch (\Exception $exception) {
                Db::rollback();
                $this->app->log->info('更新失败');
                exit('更新失败');
            }
        }
        $this->app->log->info('没有进来');
    }




    public function TaxMoney($unit_price, $number, $tax_rate)
    {
        $z_money = $unit_price * $number;
        $tax_rate = $tax_rate / 100;
        $data = [];
        $data['tax_money'] = round($z_money / ($tax_rate + 1) * $tax_rate, 2);   //  税金
        $data['money'] = round($z_money - $data['tax_money'], 2);
        return $data;
    }


    // 水电费缴纳
    public function cece()
    {

        Log::record('-----------回调信息------------------');
        $out_trade_no = 'T2021071971495';  // 订单号码
        $total_fee = '66';  // 支付金额
        $openid = 'o6ZoH5eBkkTrafPpknNN25Yb1in0'; //
        $info = Cost::where(['order_sn' => $out_trade_no])->find();
        if (empty($info)) {
            Log::record('-----------订单不存在或已经更新------------------');
            exit('订单不存在或已经更新');
        }
        Log::record('-----------info------------------');
        Log::record(json_encode($info));

        $merchant = MerchantModel::where(['id' => $info->merchant_id])->find();

        $user_info = empty($openid) ? $merchant['mobile'] : $openid;
        Log::record('-----------user_info------------------');
        Log::record($user_info);
        $socket = new  \app\common\controller\Socket();
        $result = $socket->connSocket($merchant['room_id'], $info->cost_type_id, $info->number, $info->amount / 100, $info->order_sn, $user_info);
        var_dump($result);
        MerchantModel::update(['ok' => $result . date('YmdHis', time())], ['id' => $merchant['id']]);
        exit('SUCCESS');

    }

    public function decryptToString($associatedData, $nonceStr, $ciphertext, $key = 'g8rQOEvHvSkiskFg6JurwdRml78ahRPh')
    {
        $ciphertext = \base64_decode($ciphertext);
        if (strlen($ciphertext) <= 16) {
            return false;
        }
        // ext-sodium (default installed on >= PHP 7.2)
        if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') &&
            \sodium_crypto_aead_aes256gcm_is_available()) {
            return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $key);
        }
        // ext-libsodium (need install libsodium-php 1.x via pecl)
        if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') &&
            \Sodium\crypto_aead_aes256gcm_is_available()) {
            return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $key);
        }
        // openssl (PHP >= 7.1 support AEAD)
        if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
            $ctext = substr($ciphertext, 0, -16);
            $authTag = substr($ciphertext, -16);
            return \openssl_decrypt($ctext, 'aes-256-gcm', $key, \OPENSSL_RAW_DATA, $nonceStr,
                $authTag, $associatedData);
        }
        throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
    }
}